package com.example.chat.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.chat.config.WebSocketChatServer;
import com.example.chat.enums.Code;
import com.example.chat.pojo.dto.FriendDTO;
import com.example.chat.pojo.dto.MessageDTO;
import com.example.chat.pojo.bo.Friend;
import com.example.chat.pojo.bo.Message;
import com.example.chat.mapper.FriendMapper;
import com.example.chat.pojo.res.ResModel;
import com.example.chat.service.FriendService;
import com.example.chat.util.DateUtils;
import com.example.chat.pojo.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.example.chat.constants.RedisConstants.NEW_MESSAGE_KEY;

@Service
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend> implements FriendService {

    @Autowired
    private FriendMapper friendMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private WebSocketChatServer webSocketChatServer;

    /**
     * 线程池，处理给前端推送消息任务
     */
    private static final ExecutorService THREAD_POOL= Executors.newFixedThreadPool(10);

    /**
     * 查询好友列表
     * @param cid
     * @return
     */
    @Override
    public ResModel listByCid(String cid) {
        List<UserVO> friendList = null;
        if (StrUtil.isNotEmpty(cid)){
            friendList = friendMapper.listByCid(cid);
        }
        return ResModel.success(Code.SUCCESS,friendList);
    }

    /**
     * 删除好友
     * @param friendDTO
     * @return
     */
    @Transactional
    @Override
    public ResModel deleteFriend(FriendDTO friendDTO) {
        if (StrUtil.isNotEmpty(friendDTO.getUserId()) && StrUtil.isNotEmpty(friendDTO.getFriendId())){
            LambdaQueryWrapper<Friend> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(true,Friend::getUserId,friendDTO.getUserId());
            wrapper1.eq(true,Friend::getFriendId,friendDTO.getFriendId());
            friendMapper.delete(wrapper1);
            LambdaQueryWrapper<Friend> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(true,Friend::getUserId,friendDTO.getFriendId());
            wrapper2.eq(true,Friend::getFriendId,friendDTO.getUserId());
            friendMapper.delete(wrapper2);
            return ResModel.success(Code.DELETE);
        }
        return ResModel.error(Code.UN_DELETE);
    }

    /**
     * 添加星标好友
     * @param friendDTO
     * @return
     */
    @Override
    public ResModel addStarFriend(FriendDTO friendDTO) {
        if (StrUtil.isNotEmpty(friendDTO.getUserId()) && StrUtil.isNotEmpty(friendDTO.getFriendId())){
            friendMapper.addStarFriend(friendDTO.getUserId(),friendDTO.getFriendId());
            return ResModel.success(Code.INSERT);
        }
        return ResModel.error(Code.UN_INSERT);
    }

    /**
     * 取消星标好友
     * @param friendDTO
     * @return
     */
    @Override
    public ResModel cancelStarFriend(FriendDTO friendDTO) {
        if (StrUtil.isNotEmpty(friendDTO.getUserId()) && StrUtil.isNotEmpty(friendDTO.getFriendId())){
            friendMapper.cancelStarFriend(friendDTO.getUserId(),friendDTO.getFriendId());
            return ResModel.success(Code.UPDATE);
        }
        return ResModel.error(Code.UN_UPDATE);
    }

    /**
     * 查询聊天列表
     * @param cid
     * @return
     */
    @Override
    public ResModel chatListByCid(String cid) {
        List<UserVO> chatList = null;
        if (StrUtil.isNotEmpty(cid)){
            chatList = friendMapper.chatListByCid(cid);
        }
        if (chatList != null && chatList.size() > 0){
            for (UserVO userVO : chatList) {
                String json = redisTemplate.opsForValue().get(NEW_MESSAGE_KEY + userVO.getCid() + userVO.getUserId());
                if (StrUtil.isNotEmpty(json)){
                    userVO.setCount(Long.parseLong(json));
                }
            }
        }
        return ResModel.success(Code.SUCCESS,chatList);
    }

    /**
     * 更新聊天日期及最新消息
     * @param message
     * @return
     */
    @Transactional
    @Override
    public ResModel updateChat(Message message) {
        LambdaQueryWrapper<Friend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(true,Friend::getUserId,message.getFormUserId());
        wrapper.eq(true,Friend::getFriendId,message.getToUserId());
        Friend friend = friendMapper.selectOne(wrapper);
        if (friend.getChatType().equals(0)){
            friend.setChatType(1);
            THREAD_POOL.submit(()->{
                //推送聊天列表
                UserVO newChat = friendMapper.getChatById(friend.getId());
                newChat.setChatType(1);
                webSocketChatServer.sendMessage(newChat);
            });
        }
        friend.setChatDate(new Date(DateUtils.Now().getTime() + 8 * 60 * 60 * 1000));
        friend.setLatestMessage(message.getContent());
        updateById(friend);

        LambdaQueryWrapper<Friend> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(true,Friend::getUserId,message.getToUserId());
        wrapper2.eq(true,Friend::getFriendId,message.getFormUserId());
        Friend friend2 = friendMapper.selectOne(wrapper2);
        if (friend2.getChatType().equals(0)){
            friend2.setChatType(1);
            THREAD_POOL.submit(()->{
                //推送聊天列表
                UserVO newChat = friendMapper.getChatById(friend2.getId());
                newChat.setChatType(1);
                webSocketChatServer.sendMessage(newChat);
            });
        }
        friend2.setChatDate(new Date(DateUtils.Now().getTime() + 8 * 60 * 60 * 1000));
        friend2.setLatestMessage(message.getContent());
        updateById(friend2);
        return ResModel.success(Code.SUCCESS);
    }

    /**
     * 修改聊天类型
     * @param message
     * @return
     */
    @Override
    public ResModel updateChatType(MessageDTO message) {
        LambdaQueryWrapper<Friend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(true,Friend::getUserId,message.getFormUserId());
        wrapper.eq(true,Friend::getFriendId,message.getToUserId());
        Friend friend = friendMapper.selectOne(wrapper);
        if (friend.getChatType().equals(0)){
            friend.setChatDate(new Date(DateUtils.Now().getTime() + 8 * 60 * 60 * 1000));
        }
        friend.setChatType(message.getChatType());
        updateById(friend);
        return ResModel.success(Code.SUCCESS);
    }

}
